/* manip.hh
* This file is part of ncursesxx library
* Copyright (c) 2003,2004 by Stanislav Ievlev
*
* This file is covered by the GNU Library General Public License,
* which should be included with libncursesxx as the file COPYING.
*/
#ifndef NCURSESXX_MANIP_HH__
#define NCURSESXX_MANIP_HH__

#include <iostream>
#include <ncurses/tstream.hh>

namespace ncurses
{

	//many usefull manipulators
	//I use dynamic cast here 'cause I don't want to reimplement all operators and
	//manupulators for iostream here

	typedef std::basic_ostream<char> basic_ostream;

	namespace
	{

		inline basic_ostream& set_color(basic_ostream& os, color_t color)
		{
			if (otstream *tos = dynamic_cast<otstream*>(&os))
				tos->set_fg_color(color);
			return os;
		}

		inline basic_ostream& set_attr(basic_ostream& os, attr_t attr)
		{
			if (otstream *tos = dynamic_cast<otstream*>(&os))
			{
				color_t prev = tos->color();
				tos->set_attr(attr);
				tos->set_fg_color(prev);
			}
			return os;
		}
	}

	struct set_fg_impl { attr_t mode_; color_t color_ ; } ;

	inline
	set_fg_impl setfg(color_t color, attr_t mode = WA_NORMAL)
	{
		set_fg_impl impl;
		impl.mode_ = mode;
		impl.color_ = color;
		return impl;
	}

	/**
	 * set foreground color of the terminal
	 * negative color number emits all colors reset
	 */
	inline basic_ostream& operator<<(basic_ostream& os, set_fg_impl fg)
	{
		if (otstream *tos = dynamic_cast<otstream*>(&os))
		{
			if (fg.color_ < 0)
			{
				tos->reset_colors();
				tos->set_attr();
			}
			else
			{
				tos->set_attr(fg.mode_);
				tos->set_fg_color(fg.color_);
			}
		}
		return os;
	}

	/**
	 * @todo made as a template when otstream will be template
	 */
	inline basic_ostream& black(basic_ostream& os)
	{
		return set_color(os, COLOR_BLACK);
	}

	inline basic_ostream& red(basic_ostream& os)
	{
		return set_color(os, COLOR_RED);
	}

	inline basic_ostream& green(basic_ostream& os)
	{
		return set_color(os, COLOR_GREEN);
	}

	inline basic_ostream& yellow(basic_ostream& os)
	{
		return set_color(os, COLOR_YELLOW);
	}

	inline basic_ostream& blue(basic_ostream& os)
	{
		return set_color(os, COLOR_BLUE);
	}

	inline basic_ostream& magenta(basic_ostream& os)
	{
		return set_color(os, COLOR_MAGENTA);
	}

	inline basic_ostream& cyan(basic_ostream& os)
	{
		return set_color(os, COLOR_CYAN);
	}

	inline basic_ostream& white(basic_ostream& os)
	{
		return set_color(os, COLOR_WHITE);
	}


	inline basic_ostream& normal(basic_ostream& os)
	{
		return set_attr(os, A_NORMAL);
	}

	inline basic_ostream& underline(basic_ostream& os)
	{
		return set_attr(os, A_UNDERLINE);
	}

	inline basic_ostream& reverse(basic_ostream& os)
	{
		return set_attr(os, A_REVERSE);
	}

	inline basic_ostream& blink(basic_ostream& os)
	{
		return set_attr(os, A_BLINK);
	}

	inline basic_ostream& dim(basic_ostream& os)
	{
		return set_attr(os, A_DIM);
	}

	inline basic_ostream& bold(basic_ostream& os)
	{
		return set_attr(os, A_BOLD);
	}

	inline basic_ostream& invis(basic_ostream& os)
	{
		return set_attr(os, A_INVIS);
	}

	inline basic_ostream& protect(basic_ostream& os)
	{
		return set_attr(os, A_PROTECT);
	}

	inline basic_ostream& altcharset(basic_ostream& os)
	{
		return set_attr(os, A_ALTCHARSET);
	}

}

#endif
